package com.suke.czx.authentication.handler;

import cn.hutool.core.util.CharsetUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.crypto.SecureUtil;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.api.client.util.Lists;
import com.suke.czx.authentication.detail.CustomUserDetailsUser;
import com.suke.czx.common.utils.Constant;
import com.suke.czx.common.utils.FieldConstant;
import com.suke.czx.common.utils.R;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.http.MediaType;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.PrintWriter;
import java.util.Collection;
import java.util.Optional;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

/**
 * 应用模块名称: 处理器
 * 代码描述: 登录认证成功处理器
 * copyright: AUZAR ALL RIGHTS RESERVED
 * company: AUZAR
 *
 * @author: 颜米晨
 * @date: 2021/08/27 16:31
 */
@Slf4j
@Component
public class CustomAuthenticationSuccessHandler implements AuthenticationSuccessHandler {

    @Autowired
    private RedisTemplate redisTemplate;

    private ObjectMapper objectMapper = new ObjectMapper();

    @SneakyThrows
    @Override
    public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) {
        String token = null;
        Long userId = 0L;
        String userName = null;
        Collection<String> authList = null;
        if (authentication.getPrincipal() instanceof CustomUserDetailsUser) {
            CustomUserDetailsUser userDetailsUser = (CustomUserDetailsUser) authentication.getPrincipal();
            token = SecureUtil.md5(userDetailsUser.getUsername() + System.currentTimeMillis());
            userId = userDetailsUser.getUserId();
            userName = userDetailsUser.getUsername();
            authList = userDetailsUser.getAuthorities().stream().map(GrantedAuthority::getAuthority).collect(Collectors.toList());
        }
        if (userId == 0L || StrUtil.isBlank(token)) {
            throw new RuntimeException("登录失败,请重试");
        }
        redisTemplate.opsForValue().set(StrUtil.toString(userId), token, Constant.TOKEN_EXPIRE, TimeUnit.SECONDS);
        redisTemplate.opsForValue().set(Constant.AUTHENTICATED + Constant.COLON + userId, StrUtil.join(Constant.COMMA, authList),
                Constant.AUTHENTICATED_EXPRIE, TimeUnit.SECONDS);
        response.setCharacterEncoding(CharsetUtil.UTF_8);
        response.setContentType(MediaType.APPLICATION_JSON_UTF8_VALUE);
        PrintWriter printWriter = response.getWriter();
        printWriter.append(objectMapper.writeValueAsString(R.ok().setData(Optional.ofNullable(authList).orElse(Lists.newArrayList()))
                .put(FieldConstant.USER_ID, userId).put(FieldConstant.USER_NAME, userName).put(Constant.TOKEN, token)));
    }

}
